#include "Layer.h"

#pragma unmanaged

void ProcessRGB32(
	unsigned char* dst,
	unsigned char* src,
	int x,
	int y,
	int w1,
	int h1,
	int w2,
	int h2)
{

	int p1 = (w1 * 4);
	int p2 = (w2 * 4);
    int xd = ((x < 0)) ? 0 : x;
    int yd = ((y < 0)) ? 0 : y;
    int xs = ((x < 0)) ? (0 - x) : 0;
    int ys = ((y < 0)) ? (0 - y) : 0;
    int xc = ((x + w1) > w2) ? (w1 - ((x + w1) - w2) - xs) : (w1 - xs);
    int yc = ((y + h1) > h2) ? (h1 - ((y + h1) - h2) - ys) : (h1 - ys);

	unsigned char* s = src + (xs * 4) + (ys * p1);
	unsigned char* d = dst + (xd * 4) + (yd * p2);

	for (int h = 0; h < yc; h++)
	{
		for (int w = 0; w < xc; w++)
		{
			unsigned char* s2 = s + (w * 4);
			unsigned char* d2 = d + (w * 4);

			__asm
			{
				mov eax, s2
				mov ebx, d2
				pxor mm0, mm0
				movd mm1, [ebx]
				movd mm2, [eax]
				punpcklbw mm1, mm0
				punpcklbw mm2, mm0
				//movq mm3, mm2
				//psrlq mm3, 48
				//pshufw mm3, mm3, 0
				//psubusw	mm2, mm1
				//pmullw mm3, mm2
				//psrlw mm3, 8
				//paddusw	mm3, mm1
				packuswb mm2, mm0;
				movd [ebx], mm2
				emms
			}
		}

		s += p1;
		d += p2;
	}

	/*
	__asm
	{
		mov eax, s
		mov ebx, d
		mov ecx, yc
		pxor mm0, mm0
		scanline:
			mov esi, xc
			mov edi, 0
			pixel:
				movd mm1, [ebx+edi*4]
				movd mm2, [eax+edi*4]
				punpcklbw mm1, mm0
				punpcklbw mm2, mm0
				movq mm3, mm2
				psrlq mm3, 48
				pshufw mm3, mm3, 0
				psubusw	mm2, mm1
				pmullw mm3, mm2
				psrlw mm3, 8
				paddusw	mm3, mm1
				packuswb mm3, mm0;
				movd [ebx+edi*4], mm3

			add edi, 1
			dec esi
			jnz pixel

		add eax, p1
		add ebx, p2
		dec ecx
		jnz scanline
		emms
	}*/
}

void ProcessMIX32(
	unsigned char* dst,
	unsigned char* src,
	int x,
	int y,
	int w1,
	int h1,
	int w2,
	int h2,
	int fm,
	int bm)
{

	int p1 = (w1 * 4);
	int p2 = (w2 * 4);
    int xd = ((x < 0)) ? 0 : x;
    int yd = ((y < 0)) ? 0 : y;
    int xs = ((x < 0)) ? (0 - x) : 0;
    int ys = ((y < 0)) ? (0 - y) : 0;
    int xc = ((x + w1) > w2) ? (w1 - ((x + w1) - w2) - xs) : (w1 - xs);
    int yc = ((y + h1) > h2) ? (h1 - ((y + h1) - h2) - ys) : (h1 - ys);

	unsigned char* s = src + (xs * 4) + (ys * p1);
	unsigned char* d = dst + (xd * 4) + (yd * p2);

	__asm
	{
		mov eax, s
		mov ebx, d
		mov ecx, yc
		pxor mm0, mm0
		movd mm3, fm
		movd mm4, bm

		scanline:
			mov esi, xc
			mov edi, 0
			pixel:
				movd mm1, [ebx+edi*4]
				movd mm2, [eax+edi*4]
				punpcklbw mm1, mm0
				punpcklbw mm2, mm0
				punpcklbw mm3, mm0
				punpcklbw mm4, mm0
				pshufw mm3, mm3, 0
				pshufw mm4, mm4, 0
				pmullw mm4, mm1
				pmullw mm3, mm2
				paddusw	mm4, mm3
				//psrlw mm4, 8
				packuswb mm4, mm0;
				movd [ebx+edi*4], mm4

			add edi, 1
			dec esi
			jnz pixel

		add eax, p1
		add ebx, p2
		dec ecx
		jnz scanline
		emms
	}
}


#pragma managed